package br.com.cte.xml;

import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import br.inf.portalfiscal.cte.envicte103.ObjectFactory;
import br.inf.portalfiscal.cte.envicte103.TCST;
import br.inf.portalfiscal.cte.envicte103.TCST.CST45;
import br.inf.portalfiscal.cte.envicte103.TCTe;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Compl;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Compl.Entrega;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Compl.Entrega.ComData;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Compl.Entrega.SemHora;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Compl.Fluxo;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Dest;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Emit;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Ide;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Ide.Toma03;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Imp;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.InfCTeNorm;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.InfCTeNorm.InfCarga;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.InfCTeNorm.InfCarga.InfQ;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.InfCTeNorm.Rodo;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Rem;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.Rem.InfNFe;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.VPrest;
import br.inf.portalfiscal.cte.envicte103.TCTe.InfCte.VPrest.Comp;
import br.inf.portalfiscal.cte.envicte103.TEndeEmi;
import br.inf.portalfiscal.cte.envicte103.TEndereco;
import br.inf.portalfiscal.cte.envicte103.TEnviCTe;
import br.inf.portalfiscal.cte.envicte103.TUf;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;

public class GerandoEnviCTeJAXB {

    public static void main(String[] args) {
        try {
            TEnviCTe enviCTe = new TEnviCTe();

            enviCTe.setIdLote("1");
            enviCTe.setVersao("1.04");
            //enviCTe.set
            enviCTe.getCTe().add(gerarCTe(enviCTe));

            info("XML NF-e: " + strValueOf(enviCTe));
        } catch (Exception e) {
            error(e.toString());
        }
    }

    private static TCTe gerarCTe(TEnviCTe enviCTe) {
        TCTe tcTe = new TCTe();
        InfCte infCte = new InfCte();

        infCte.setId("CTe43110694691623003053570000000000010000000000");
        infCte.setVersao("1.04");
       // infCte.
        infCte.setIde(dadosDeIdentificacao());
        infCte.setCompl(dadosDeComplementares());
        infCte.setEmit(dadosDoEmitente());
        infCte.setRem(dadosDoRemetente());
        infCte.setDest(dadosDoDestinatario());
        infCte.setVPrest(dadosDaPrestacaoDoServico());

        infCte.setImp(dadosDosImpostos());
        infCte.setInfCTeNorm(dadosNormalSubstituto());

        tcTe.setInfCte(infCte);
        return tcTe;
    }

    private static InfCTeNorm dadosNormalSubstituto() {
        InfCTeNorm infCTeNorm = new InfCTeNorm();

        InfCarga infCarga = new InfCarga();
        infCarga.setVMerc("0");
        infCarga.setProPred("PNEUS");

        InfQ infQ = new InfQ();
        infQ.setCUnid("01");
        infQ.setTpMed("PESO");
        infQ.setQCarga("31");
        infCarga.getInfQ().add(infQ);
        infCTeNorm.setInfCarga(infCarga);

        Rodo rodo = new Rodo();
        rodo.setRNTRC("12340023134012");
        rodo.setDPrev("2009-03-04");
        rodo.setLota("0");
        infCTeNorm.setRodo(rodo);

        return infCTeNorm;
    }

    private static Imp dadosDosImpostos() {
        Imp imp = new Imp();

        TCST tcst = new TCST();
        CST45 cst45 = new CST45();
        cst45.setCST("40");
        tcst.setCST45(cst45);
        

        imp.setICMS(tcst);
        return imp;
    }

    private static VPrest dadosDaPrestacaoDoServico() {
        VPrest prest = new VPrest();
        prest.setVTPrest("59.69");
        prest.setVRec("59.69");

        Comp comp1 = new Comp();
        comp1.setXNome("FRETE VALOR");
        comp1.setVComp("50.78");
        prest.getComp().add(comp1);

        Comp comp2 = new Comp();
        comp2.setXNome("GRIS");
        comp2.setVComp("5.40");
        prest.getComp().add(comp2);

        Comp comp3 = new Comp();
        comp3.setXNome("PEDAGIO");
        comp3.setVComp("3.51");
        prest.getComp().add(comp3);

        return prest;
    }

    private static Dest dadosDoDestinatario() {
        Dest dest = new Dest();
        dest.setCNPJ("12341234123413");
        dest.setIE("1234123465");
        dest.setXNome("NOME DO DESTINATARIO");

        TEndereco enderDest = new TEndereco();
        enderDest.setXLgr("RUA DO DESTINATARIO");
        enderDest.setNro("44");
        enderDest.setXBairro("CENTRO");
        enderDest.setCMun("4307005");
        enderDest.setXMun("ERECHIM");
        enderDest.setCEP("99700000");
        enderDest.setUF(TUf.valueOf("RS"));
        dest.setEnderDest(enderDest);

        return dest;
    }

    private static Rem dadosDoRemetente() {
        Rem rem = new Rem();
        rem.setCNPJ("12431234000124");
        rem.setIE("1234123445");
        rem.setXNome("NOME DO REMETENTE");
        rem.setFone("005599999999");

        TEndereco enderReme = new TEndereco();
        enderReme.setXLgr("RUA DO REMETENTE");
        enderReme.setNro("2650");
        enderReme.setXBairro("CENTRO");
        enderReme.setCMun("4316907");
        enderReme.setXMun("SANTA MARIA");
        enderReme.setCEP("97070000");
        enderReme.setUF(TUf.valueOf("RS"));
        
        rem.setEnderReme(enderReme);

        /**
         * Para informar dados de uma NF usar a Classe "InfNF"
         */
        InfNFe infNFe = new InfNFe();
        infNFe.setChave("12349781239487129834710289347102983471212322");
        rem.getInfNFe().add(infNFe);

        return rem;
    }

    private static Emit dadosDoEmitente() {
        Emit emit = new Emit();

        emit.setCNPJ("94691623003053");
        emit.setIE("1091234932");
        emit.setXNome("EMITENTE EXEMPLO S.A.");
        emit.setXFant("EMITENTE EXEMPLO");

        TEndeEmi enderEmit = new TEndeEmi();

        enderEmit.setXLgr("R EXEMPLO CT-E");
        enderEmit.setNro("142");
        enderEmit.setXBairro("CENTRO DA CIDADE");
        enderEmit.setCMun("4316907");
        enderEmit.setXMun("SANTA MARIA");
        enderEmit.setCEP("97070000");
        enderEmit.setUF(TUf.valueOf("RS"));
        emit.setEnderEmit(enderEmit);

        return emit;
    }

    private static Compl dadosDeComplementares() {
        Compl compl = new Compl();

        compl.setXCaracSer("NORMAL");
        compl.setXEmi("JAVAC COMMUNITY EXEMPLO CT-E");

        Fluxo fluxo = new Fluxo();
        fluxo.setXOrig("SM");
        fluxo.setXDest("ER");
        compl.setFluxo(fluxo);

        Entrega entrega = new Entrega();

        ComData comData = new ComData();
        comData.setTpPer("2");
        comData.setDProg("2009-03-04");
        entrega.setComData(comData);

        SemHora semHora = new SemHora();
        semHora.setTpHor("0");
        entrega.setSemHora(semHora);

        compl.setEntrega(entrega);
        compl.setXObs("ICMS ISENTO");
        return compl;
    }

    private static Ide dadosDeIdentificacao() {
        Ide ide = new Ide();

        ide.setCUF("43");
        ide.setCCT("85660634");
        ide.setCFOP("5353");
        ide.setNatOp("SERVICO DE TRANSPORTE");
        ide.setForPag("0");
        ide.setMod("57");
        ide.setSerie("0");
        ide.setNCT("1");
        ide.setDhEmi("2011-06-18T12:15:00");
        ide.setTpImp("1");
        ide.setTpEmis("1");
        ide.setCDV("0");
        ide.setTpAmb("2");
        ide.setTpCTe("0");
        ide.setProcEmi("0");
        ide.setVerProc("1.04");
        
        //ide.setC;
        
        ide.setCMunEmi("4316907");
        ide.setXMunEmi("SANTA MARIA");
        ide.setUFEmi(TUf.valueOf("RS"));
        ide.setModal("01");
        ide.setTpServ("0");
        ide.setCMunIni("4316907");
        ide.setXMunIni("SANTA MARIA");
        ide.setUFIni(TUf.valueOf("RS"));
        ide.setCMunFim("4307005");
        ide.setXMunFim("ERECHIM");
        ide.setUFFim(TUf.valueOf("RS"));
        ide.setRetira("1");

        Toma03 toma03 = new Toma03();
        toma03.setToma("0");
        ide.setToma03(toma03);

        return ide;
    }

    /**
     * Método que Converte o Objeto em String.
     *
     * @return
     * @throws JAXBException
     */
    private static String strValueOf(TEnviCTe enviCTe) throws JAXBException, IOException {
        JAXBContext context = JAXBContext.newInstance(TEnviCTe.class);
        Marshaller marshaller = context.createMarshaller();
        JAXBElement<TEnviCTe> element = new ObjectFactory().createEnviCTe(enviCTe);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

//        File f = new File("C:/Users/Marcio/Documents/NetBeansProjects/CteFrederico/XmlGerados/enviCTe.xml");
//        try {
//            marshaller.marshal(element, new FileOutputStream(f));
//        } catch (FileNotFoundException ex) {
//            Logger.getLogger(GerandoEnviCTeJAXB.class.getName()).log(Level.SEVERE, null, ex);
//        }

        StringWriter sw = new StringWriter();
        marshaller.marshal(element, sw);

        String xml = sw.toString();
        xml = xml.replaceAll("xmlns:ns2=\"http://www.w3.org/2000/09/xmldsig#\" ", "");
        xml = xml.replaceAll("<CTe>", "<CTe xmlns=\"http://www.portalfiscal.inf.br/cte\">");

        escreveXml(xml);
        return xml;
    }

    private static void escreveXml(String s) throws IOException {
        FileWriter o = new FileWriter("C:/Frotas/Cte/Cte/XmlGerados/enviCTe.xml");
        PrintWriter out = new PrintWriter(o);
        out.print(s);
        out.flush();
        out.close();
    }

    /**
     * Log ERROR.
     *
     * @param error
     */
    private static void error(String error) {
        System.out.println("| ERROR: " + error);
    }

    /**
     * Log INFO.
     *
     * @param info
     */
    private static void info(String info) {
        System.out.println("| INFO: " + info);
    }
}
